オンプレ環境からS3へのファイル転送方式についてこれまで試したパターンまとめ
西澤です。AWS上にシステムを移行する上で、毎度のようにご相談を受けるのが、S3へのファイル転送をどうするか?という問題です。ビッグデータの元となる大量のファイル、RDBのダンプファイル、その他のバックアップファイル等を含め、安価で堅牢なS3にまずはデータを格納し、そこから自由に利用したいというユーザの希望を実現する為に、まずは何よりもS3にファイルを持っていかなければなりません。
今回は、過去のブログも遡りつつ、これまで試してみた各種転送方式をご紹介し、それぞれのユースケースを整理しておこうと思います。また、この記事は書きっぱなしにするのではなく、今後必要に応じてメンテナンスもすることで、再利用できるような記事に育てていきたいなと思っています(執筆時点での意気込みであり、何かを保証するものではありません)。
前提
Amazon Kinesis Streamsを利用するようなリアルタイム処理については、ここでは検討していません。それなりのファイル数やファイルサイズも転送するケースは想定していますが、万一エラーになっても再送すれば良い、というレベルでの方式を検討し、リアルタイム性や可用性の高い構成はここでは考えないものとします。
最初に検討すべき転送方式はAWS CLI
AWS S3にファイルを転送する方法として、いくつか方法がありますが、まずは、AWS CLIのハイレベルS3コマンドの利用を検討しましょう。UNIX、Linuxコマンドを使い慣れた方ならお馴染みのオプションで、ファイルの受け渡しが可能で、syncオプションでは差分転送も可能ですし、ファイルサイズが大きければ、自動でマルチパートアップロードも行ってくれます。
- AWS Command Line Interface での高レベルの S3 コマンドの使用 - AWS Command Line Interface
- s3 — AWS CLI 1.11.93 Command Reference
都元さんのこの記事では、標準入出力との受け渡しも紹介されています。
もちろん他のSDKを利用するのもありだと思います。AWSマネージメントコンソールや他のサードパーティツールを利用するのも良いと思いますが、GUIのツールはパフォーマンス面で問題となることが多いという印象です。ちなみに、これらの方式で行われる転送はすべてHTTPSが利用されます。
S3ファイル転送における課題とその解決策
さて、ついに本題です。AWS CLIによるS3へのファイル転送では、何かしらの課題が発生するケースがあります。ここからその代表的なものを整理して、実際に試した転送方式についてご紹介してみたいと思います。
課題1:転送性能が不足
ファイルが大量だったり、ファイルサイズが非常に大きい場合、S3へのファイル転送について十分な性能が出ないケースがありました。データの移行に時間がかかり過ぎてしまうと、本来取り組みたい環境移行のスケジュールにも差し障りがありますので、少しでも速くデータを転送方式を模索しました。
Direct Connectのパブリック接続
1つの解決策は、Direct Connectのパブリック接続を利用するという方法になると思います。ですが、キャリアが提供してくれる共用プランでは利用できず、それなりに高額となるようなので、私個人としてはこれまで実際にパブリックなDirect Connect構成を利用されているお客様を担当する機会に恵まれませんでした。初っ端からあれですが、ここでは紹介だけにとどめておきたいと思います。
UDP転送ツール
サイズの大きいファイルを転送するケースでは、Tsunami UDP等の最適化された転送ツールを検討すると良いでしょう。
暗号化機能も加え、より高機能に利用できるExpeDat Gatewayも試してみる機会がありました。転送はUDPが利用される為、失敗した場合は1からリトライが必要となる点には注意が必要でした。
並列度をチューニング
これはクラウドの特徴でもありますが、S3も例に漏れず、シーケンシャルな処理よりも、並列処理でより性能が出るように設計されています。AWS CLIに限らず、S3へのファイル転送を行う際には、並列度に注意すると大幅に性能が改善するケースがありますので、下記ブログも参考にしてみてください。
遠くのリージョンのS3に転送したい
海外のリージョンのS3にファイル転送したい場合は、エッジロケーションを経由してファイルのアップロードができる"S3 Transfer Acceleration"を利用すると良いでしょう。転送料金が若干割高にはなりますが、自動的に最も近いエッジロケーションを選択し、ファイルを高速にアップロード/ダウンロードすることが可能です。
課題2:閉域網から転送したい
HTTPSが利用されるとは言え、転送データ内にデリケートな情報が含まれる場合、インターネットを介さずファイル転送を行いたいというケースは多いと思います。VPC内に一時的に転送されてくるファイルの受け口を用意すれば、S3用のVPCエンドポイントを経由してS3にファイルを配置することが可能です。
Proxyサーバを利用したS3へのファイル転送
手っ取り早い方式としては、EC2でProxyサーバを間に構築するのが簡単です。ただし、このProxyサーバに十分なネットワーク性能が求められる点には注意が必要です。
課題3:クライアント環境で転送に使える方式が限られている
CMS等のクライアント環境の制約により、AWS CLIやSDKを利用するのが難しいケースもよく見られるパターンです。その場合には、ファイル転送では昔からよく利用される、FTP、SFTP等の汎用性の高い機能を利用して、クライアントからのデータ通信を構成します。
FTP/SFTPからlsyncdを利用してS3へのファイル転送
結果的に、課題2についてもこの方式でクリアすることができるのですが、EC2でFTPサーバ、SFTPサーバを用意し、受信したファイルをlsyncdを用いてS3に転送するのがよく用いられる方式です。このパターンでは、lsyncdの監視ファイル数の上限に注意しつつ、障害発生時にローカルディスクとS3とのファイルを同期する方法を事前に検討しておくと良いでしょう。
File Gatewayを利用してS3へファイル転送
lsyncdの代わりに、S3と自動的に同期を取ってくれるFile Gatewayを検討してみるのも良いでしょう。File GatewayはAWS Storage Gatewayサービスの一部として提供されるバーチャルアプライアンスで、S3への自動同期機能を備えたNFSサーバとして動作します。S3との同期の仕組みを作らずに、マネージドサービスとしてNFSサーバを利用することができますが、キャッシュとして適切なサイズのEBSボリュームを割り当てる必要があります。このNFSサーバのスペック、キャッシュサイジングに注意が必要です。
課題4:EBSは使いたくない
特に課題3で利用するlsyncdやFile Gatewayでは、ファイルを一時的に受けることができる十分なサイズを有したEBSボリュームを用意する必要があります。そもそも、EBSボリュームはサイズが大きくなるとコストがかさみますし、EBSとS3で同期を取る仕組みに課題が残る可能性がある為、EBSを使わずに直接S3に書き込む仕組みがあった方が望ましいケースがあると思います。
FUSE(s3fs-use,goofys)でS3をマウントして利用
そこで、s3fs-use,goofys等を利用してS3をファイルシステムのようにマウントして利用します。大きなEBSボリュームは不要になり、同期状態も気にしなくて良いという一方で、実際にはファイルシステムで管理されるストレージでは無いS3に対して、ユーザが誤った認識を持ちやすいこともあり、この構成はあまり推奨されていません。特に同じファイルを何度も更新、削除、再作成するようなケースでは、想定した通りの動作とならないケースもありますので注意しましょう。
まとめ
S3へのファイル転送パターンを整理し、それぞれのユースケースや注意事項についてまとめてみました。実際にお客様と相談した上で、それぞれ試してみたのですが、一長一短あり、要件によっても使い分けが必要となる為、整理したいと思っていたことが整理できてスッキリしました。
どこかの誰かのお役に立てば嬉しいです。